/*
 * Tester.java
 *
 * Created on February 19, 2007, 9:31 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.group1E;

import edu.byu.isys413.group1E.data.*;
import edu.byu.isys413.group1E.gui.*;
import java.sql.*;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

/**
 * A simple tester class for my data layer.
 *
 * @author Conan C. Albrecht
 */
public class Tester {
    
    public static void main(String args[]) {
        try {
            //see if the user wants to open the GUIs or just run the tester class
            int opt = JOptionPane.showConfirmDialog(null, "Would you like to open the GUI?","Open GUI?", JOptionPane.YES_NO_OPTION);
            if(opt == JOptionPane.YES_OPTION){
                try {                                                                           //change appearance according to system
                    String look = UIManager.getSystemLookAndFeelClassName();
                    UIManager.setLookAndFeel(look);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                CustomerFrame newCustFrame = new CustomerFrame();                               //initialize frame
                newCustFrame.setLocationRelativeTo(null);                                       //set frame location to center of screen
                newCustFrame.setVisible(true);                                                  //display frame
            }else{
                
                // clear out the database and cache (you'd never do this in production)
                System.out.println("\nTesting Milestone 1:\n");
                
                Cache.getInstance().clear();
                Connection conn = ConnectionPool.getInstance().get();
                conn.setAutoCommit(false);
                Statement stmt = conn.createStatement();
//                stmt.executeUpdate("DELETE FROM MEMBER_INTEREST");
//                stmt.executeUpdate("DELETE FROM CUSTOMER");
//                stmt.executeUpdate("DELETE FROM MEMBERSHIP");
//                stmt.executeUpdate("DELETE FROM AREA_OF_INTEREST");
//
//                stmt.close();
//                conn.commit();
//                ConnectionPool.getInstance().release(conn);
//                System.out.println("Database and Cache have been cleared.\n");
                /* Testing Customer*/
                System.out.println("===========================================================================");
                System.out.println("Testing Customer:\n");
                //Put new test data in Customer using Insert
                CustomerBO cust = CustomerDAO.getInstance().create();
                cust.setCustFirstName("Conan");
                cust.setCustMI("C.");
                cust.setCustLastName("Albrecht");
                cust.setCustAddr("1234 E. 4th Street");
                cust.setCustCity("Provo");
                cust.setCustState("UT");
                cust.setCustZip("84606");
                cust.setCustPhone("801-222-2222");
                cust.setCustEmail("cca@byu.edu");
                CustomerDAO.getInstance().save(cust);
                System.out.println("Customer created: " + cust.getCustID() + ", Conan C. Albrecht, 1234 E. 4th Street, Provo, UT, 84606, 801-222-2222, cca@byu.edu");
                
                //Create a second customer
                CustomerBO cust2b = CustomerDAO.getInstance().create();
                cust2b.setCustFirstName("Gary");
                cust2b.setCustMI("");
                cust2b.setCustLastName("Hansen");
                cust2b.setCustAddr("1234 N. 100 S.");
                cust2b.setCustCity("Payson");
                cust2b.setCustState("UT");
                cust2b.setCustZip("84605");
                cust2b.setCustPhone("801-222-2223");
                cust2b.setCustEmail("ghansen@byu.edu");
                CustomerDAO.getInstance().save(cust2b);
                System.out.println("Another customer created: Gary Hansen, 1234 N. 100 S., Payson, UT, 84605, 801-222-2223, ghansen@byu.edu");
                
                //Update the test data in Customer using Update
                cust.setCustPhone("801-222-2233");
                CustomerDAO.getInstance().save(cust);
                System.out.println("\nFirst customer phone updated: " + cust.getCustID() + ", " + cust.getCustFirstName() + " " + cust.getCustMI() + " " +
                        cust.getCustLastName() + ", " + cust.getCustAddr() + ", " + cust.getCustCity() + ", " + cust.getCustState() + ", " + cust.getCustZip() +
                        ", " + cust.getCustPhone() + ", " + cust.getCustEmail() + ", " + cust.isAlreadyInDB() + ", " + cust.isIsDirty() + "\n");
                
                // test that the exact same object will come out of the cache if asked for
                Cache c = Cache.getInstance();
                CustomerBO cust2 = (CustomerBO)c.get(cust.getCustID());
                System.out.println("Requested direct from Cache: cust==cust2 -> " + (cust == cust2));
                System.out.println("Customer retrieved: " + cust2.getCustID() + ", " + cust2.getCustFirstName() + " " + cust2.getCustMI() + " " +
                        cust2.getCustLastName() + ", " + cust2.getCustAddr() + ", " + cust2.getCustCity() + ", " + cust2.getCustState() + ", " + cust2.getCustZip() +
                        ", " + cust2.getCustPhone() + ", " + cust2.getCustEmail() + ", " + cust2.isAlreadyInDB() + ", " + cust2.isIsDirty() + "\n");
                
                //test that the object can be retrieved via the read method
                CustomerBO cust3 = CustomerDAO.getInstance().read(cust.getCustID());
                System.out.println("From Cache through Read: cust==cust3 -> " + (cust == cust3));
                System.out.println("Customer retrieved: " + cust3.getCustID() + ", " + cust3.getCustFirstName() + " " + cust3.getCustMI() + " " +
                        cust3.getCustLastName() + ", " + cust3.getCustAddr() + ", " + cust3.getCustCity() + ", " + cust3.getCustState() + ", " + cust3.getCustZip() +
                        ", " + cust3.getCustPhone() + ", " + cust3.getCustEmail() + ", " + cust3.isAlreadyInDB() + ", " + cust3.isIsDirty() + "\n");
                
                /* Testing Membership*/
                System.out.println("===========================================================================");
                System.out.println("Testing Membership:\n");
                // create a membership and save using Insert
                MembershipBO member = MembershipDAO.getInstance().create();
                member.setCreditCardType("Visa");
                member.setCreditCardNum("1234-5678-4321-8765");
                member.setCreditCardExpMonth(9);
                member.setCreditCardExpYear(2010);
                member.setMemberStartDate("2006-10-14");
                member.setMemberExpireDate("2008-10-14");
                member.setCust(cust);
                cust.setCustMembership(member);
                CustomerDAO.getInstance().save(cust);           //calls the save() method in membership as well
                System.out.println("Membership created: " + member.getMembershipID() + "Visa, 1234-5678-4321-8765, 9, 2010, 2006-10-14, 2008-10-14");
                
                // update a membership and save using Update
                member.setCreditCardExpMonth(11);
                member.setCreditCardExpYear(2015);
                MembershipDAO.getInstance().save(member);
                System.out.println("Membership udated: 11, 2015");
                
                // test that the exact same object will come out of the cache if asked for
                MembershipBO member2 = (MembershipBO)c.get(member.getMembershipID());
                System.out.println("\nRequested direct from Cache: member==member2 -> " + (member == member2));
                System.out.println("Membership retrieved: " + member2.getCreditCardType() + ", " + member2.getCreditCardNum() + ", " +
                        member2.getCreditCardExpMonth() + ", " + member2.getCreditCardExpYear() + "\n");
                
                //test the same through the read method
                MembershipBO member3 = MembershipDAO.getInstance().read(member.getMembershipID());
                System.out.println("From Cache through Read: member==member3 -> " + (member == member3));
                System.out.println("Membership retrieved: " + member2.getCreditCardType() + ", " + member2.getCreditCardNum() + ", " +
                        member2.getCreditCardExpMonth() + ", " + member2.getCreditCardExpYear() + "\n");
                
                
                /* Testing Area of Interest*/
                System.out.println("===========================================================================");
                System.out.println("Testing Area Of Interest:\n");
                //add AOI
                AreaOfInterestBO aoi = AreaOfInterestDAO.getInstance().create();
                aoi.setDescription("New Printers");
                AreaOfInterestDAO.getInstance().save(aoi);
                System.out.println("AOI created: " + aoi.getAOI_ID() + ", " + aoi.getDescription() + "\n");
                
                //add AOI
                AreaOfInterestBO aoi2 = AreaOfInterestDAO.getInstance().create();
                aoi2.setDescription("High-Def Television");
                AreaOfInterestDAO.getInstance().save(aoi2);
                System.out.println("Another AOI created: " + aoi2.getAOI_ID() + ", " + aoi2.getDescription() + "\n");
                
                // test that the exact same object will come out of the cache if asked for
                AreaOfInterestBO aoi3 = (AreaOfInterestBO)c.get(aoi.getAOI_ID());
                System.out.println("First AOI requested direct from Cache: aoi==aoi3 -> " + (aoi == aoi3));
                System.out.println("AOI retrieved: " + aoi3.getAOI_ID() + ", " + aoi3.getDescription() + "\n");
                
                //test the same through the read method
                AreaOfInterestBO aoi4 = (AreaOfInterestBO)AreaOfInterestDAO.getInstance().read(aoi2.getAOI_ID());
                
                System.out.println("Second AOI from Cache through Read: aoi2==aoi4 -> " + (aoi2 == aoi4));
                System.out.println("AOI retrieved: " + aoi4.getAOI_ID() + ", "+ aoi4.getDescription() + "\n");
                
                
                System.out.println("===========================================================================");
                System.out.println("Testing Member_Interest:\n");
                
                //add AOIs to Membership
                member.addInterest(aoi);
                member.addInterest(aoi2);
                MembershipDAO.getInstance().save(member);       //Inserts the new areas of interest into the Member_Interest table
                System.out.println("The two areas of interest have been added to the DB for Conan Albrecht.");
                
                ArrayList<AreaOfInterestBO> memberList = MembershipDAO.getInstance().read(member.getMembershipID()).getInterestList();
                //read contents of the list
                System.out.println("Conan's Areas of Interest read from DB:");
                for(int i=0;i<memberList.size();i++){
                    System.out.println(memberList.get(i).getDescription());
                }
                
                /* Reading all Date for Milestone 1*/
                System.out.println("===========================================================================");
                System.out.println("Retrieving All Data for Milestone 1:");
                //get the customers on the account
                Connection conn2 = ConnectionPool.getInstance().get();
                stmt = conn2.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT * FROM Customer");
                conn2.commit();
                System.out.println("\nCustomers: ");
                while(rs.next()){
                    System.out.println(rs.getString("CustFirstName"));
                }
                
                rs = stmt.executeQuery("SELECT * FROM Membership");
                System.out.println("\nMembership: ");
                while(rs.next()){
                    System.out.println(rs.getString("creditCardNum"));
                }
                
                rs = stmt.executeQuery("SELECT * FROM Area_Of_Interest");
                System.out.println("\nAreas Of Interest: ");
                while(rs.next()){
                    System.out.println(rs.getString("Description"));
                }
                
                rs = stmt.executeQuery("SELECT * FROM Member_Interest");
                System.out.println("\nMembership_Interest: ");
                while(rs.next()){
                    System.out.println(rs.getString("MembershipID") + " " + rs.getString("InterestID"));
                }
                
                stmt.close();
                ConnectionPool.getInstance().release(conn2);
                // reload everything from scratch to test whether the read methods work
                // this essentially is like restarting the entire system since
                // we're going to clear the cache out
                Cache.getInstance().clear(); // you'd never clear the cache in production (we do so for testing)
                System.out.println("The Cache has been cleared for a clean read from the DB:");
                CustomerBO cust5 = CustomerDAO.getInstance().read(cust2.getCustID());
                System.out.println("Customer First name is: " + cust5.getCustFirstName());
                System.out.println("Customer Last name is: " + cust5.getCustLastName());
                System.out.println("MembershipID is: " + cust5.getCustMembership().getMembershipID());
                
                /******************************************************************************************************/
                /**********************************MILESTONE 2*********************************************************/
                /******************************************************************************************************/
                
                System.out.println("\n===========================================================================");
                System.out.println("\nStarting Milestone 2:");
                
                /* Testing Employee*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Employee:");
                
                //Create the Employee
                EmployeeBO emp = EmployeeDAO.getInstance().create();
                emp.setEmpFirstName("Preston");
                emp.setEmpMI("D");
                emp.setEmpLastName("Kurschinske");
                emp.setEmpAddress("456 S. Ritzy Rd.");
                emp.setEmpCity("Nephi");
                emp.setEmpState("UT");
                emp.setEmpZip("86767");
                emp.setEmpPhone("801-876-3403");
                emp.setEmpSocSecNum("546-665-9898");
                emp.setHireDate("2004-2-13");
                emp.setFireDate(null);
                //read the Position object to get the manager position for this employee
                emp.setPosition(PositionDAO.getInstance().read("0000011106a3cc3a0000007f000002"));
                emp.setPassword("h0wdy123");
                //save using the insert method
                EmployeeDAO.getInstance().save(emp);        //save the employee to the DB
                System.out.println("Employee created: " + emp.getEmpFirstName() + " " + emp.getEmpMI() + " " +
                        emp.getEmpLastName() + ", pwd: " + emp.getPassword());
                
                //read the same employee out of the cache
                EmployeeBO emp2 = EmployeeDAO.getInstance().read(emp.getEmployeeID());
                System.out.println("Requested from Cache through Read: emp==emp2 -> " + (emp == emp2));
                System.out.println("Employee retrieved: " + emp2.getEmployeeID() + ", " + emp2.getEmpFirstName() +
                        " " + emp2.getEmpMI() + " " + emp2.getEmpLastName() + ", " + emp2.getEmpAddress() + ", " +
                        emp2.getEmpCity() + ", " + emp2.getEmpState() + " " + emp2.getEmpZip() + ", " + emp2.getEmpPhone() +
                        ", " + emp2.getEmpSocSecNum() + ", " + emp2.getHireDate() + ", " + emp2.getFireDate() + ", " +
                        emp2.getPosition().getPositionID() + ", " + emp2.getPassword());
                
                //test the update method
                emp.setPassword("h0wdy!");
                EmployeeDAO.getInstance().save(emp);
                Cache.getInstance().clear();
                //read the employee from the DB after the cache has been cleared
                EmployeeBO emp3 = EmployeeDAO.getInstance().read(emp.getEmployeeID());
                System.out.println("Employee updated (Password changed): " + emp3.getEmpFirstName() + " " + emp3.getEmpMI() + " " +
                        emp3.getEmpLastName() + ", pwd: " + emp3.getPassword());
                
                /* Testing Store*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Store:");
                
                //create the Store
                StoreBO store = StoreDAO.getInstance().create();
                store.setAddress("123 S. MyStuff Blvd.");
                store.setCity("Nephi");
                store.setState("UT");
                store.setZip("80767");
                store.setPhone("801-876-9850");
                store.setManagerID(emp.getEmployeeID());
                store.setAlreadyInDB(false);
                StoreDAO.getInstance().save(store);
                //display contents of the storeon to test the get methods
                System.out.println("Store created: " + store.getStoreID() + ", " + store.getAddress() + ", " +
                        store.getCity() + ", " + store.getState() + " " + store.getZip() + ", " +
                        store.getPhone() + ", " + store.getManager().getEmpFullName() + " (ID#: " + store.getManagerID() + ")");
                
                // test that the exact same storeon object will come out of the cache if asked for
                StoreBO store2 = StoreDAO.getInstance().read(store.getStoreID());
                System.out.println("Requested from Cache through Read: store==store2 -> " + (store == store2));
                System.out.println("Store retrieved: ID = " + store2.getStoreID() + ", " + store2.getAddress());
                
                //test the update method, then read it from the DB after saving
                store.setPhone("801-989-6443");
                StoreDAO.getInstance().save(store);
                Cache.getInstance().clear();
                StoreBO store3 = StoreDAO.getInstance().read(store.getStoreID());
                System.out.println("Store updated (Phone changed): " + store3.getStoreID() + ", " + store3.getAddress() +
                        ", " + store3.getPhone());
                
                
                /* Testing Session*/
                System.out.println("\n===========================================================================");
                System.out.println("Creating Session Object");
                
                //create the Session object using the Employee and Store information from above
                Session s = Session.create(emp, store);
                System.out.println("Session created: ID = " + s.getSessionID() + ", Store = " + s.getStore().getStoreID() +
                        ", Emp = " + s.getEmployee().getEmpFullName());
                
                /* Testing Position*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Position (not required for MS2):");
                
                //create the Store
                PositionBO pos = PositionDAO.getInstance().create();
                pos.setSalary(150000.00);
                pos.setTitle("Regional Manager");
                PositionDAO.getInstance().save(pos);        //save the position
                
                //get the position from Cache
                PositionBO pos2 = PositionDAO.getInstance().read(pos.getPositionID());
                System.out.println("Requested through Read: pos==pos2 -> " + (pos == pos2));
                System.out.println("Position retrieved: ID = " + pos2.getPositionID() + ", " + pos2.getTitle() + ", " + pos2.getSalary());
                
                //Update then get the position from the DB
                pos.setSalary(120000);
                PositionDAO.getInstance().save(pos);
                Cache.getInstance().clear();
                PositionBO pos3 = PositionDAO.getInstance().read(pos.getPositionID());
                System.out.println("Position updated then retrieved from DB: ID = " + pos3.getPositionID() + ", " + pos3.getTitle() + ", " + pos3.getSalary());
                
                /* Testing Coupon*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Coupon:");
                CouponBO coup = CouponDAO.getInstance().create();
                coup.setCoupAmount(3.0);
                coup.setCoupPercent(0.0);
                coup.setDescription("Good customer discount.");
                coup.setExpireDate("2007-12-15");
                coup.setRevSrcType("sale");
                coup.setStartDate("2007-01-01");
                coup.setAlreadyInDB(false);
                CouponDAO.getInstance().save(coup);
                //display contents of the coupon to test the get methods
                System.out.println("Coupon created: " + coup.getCouponID() + ", " + coup.getDescription() + ", " +
                        coup.getCoupAmount() + ", " + coup.getCoupPercent() + ", " + coup.getStartDate() + ", " +
                        coup.getExpireDate() + ", " + coup.getRevSrcType());
                
                // test that the exact same coupon object will come out of the cache if asked for
                c = Cache.getInstance();
                CouponBO coup2 = (CouponBO)c.get(coup.getCouponID());
                System.out.println("Requested from Cache: coup==coup2 -> " + (coup == coup2));
                System.out.println("Coupon retrieved: " + coup2.getCouponID() + ", " + coup2.getDescription() + ", " +
                        coup2.getCoupAmount() + ", " + coup2.getCoupPercent() + ", " + coup2.getStartDate() + ", " +
                        coup2.getExpireDate() + ", " + coup2.getRevSrcType());
                
                //test that the object can be updated then retrieved via the read method
                coup.setExpireDate("2007-12-31");
                CouponDAO.getInstance().save(coup);
                Cache.getInstance().clear();
                CouponBO coup3 = CouponDAO.getInstance().read(coup.getCouponID());
                System.out.println("Coupon updated then retrieved from DB: " + coup3.getCouponID() + ", " + coup3.getDescription() + ", " +
                        coup3.getCoupAmount() + ", " + coup3.getCoupPercent() + ", " + coup3.getStartDate() + ", " +
                        coup3.getExpireDate() + ", " + coup3.getRevSrcType());
                
                /* Testing Transaction and TransLine*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Transaction:");
                //create and build the Transaction
                TransactionBO trans = TransactionDAO.getInstance().create();
                trans.setSession(s);                                //setSession sets the StoreID and EmployeeID variables
                trans.setCustomerID(cust.getCustID());
                trans.setTransDate("2007-03-11");
                trans.setTransStatus("Pending");        //set as 'Pending' just to test the change of that field
                trans.setTransTaxRate(0.0625);
                //add transactionLines for all Revenue Sources (for convenience) and apply all coupons as applicable
                ArrayList<RevenueSourceBO> revSrcList = SvcRepairDAO.getInstance().readAll();
                for(int z=0; z<revSrcList.size(); z++){
                    //leave out "Laptop Repair" since it definitely requires 'Pending' status
                    SvcRepairBO srx = (SvcRepairBO)revSrcList.get(z);
                    if(!srx.getDescription().equals("Laptop Repair")){
                        TransLineBO txLine = TransLineDAO.getInstance().create();
                        txLine.setTransactionID(trans.getTransID());
                        txLine.setRevSrc(revSrcList.get(z));
                        trans.addTxLine(txLine);
                    }
                }
                //get all of the coupons  (for convenience)
                ArrayList<CouponBO> coupList = CouponDAO.getInstance().getInstance().readAllCoup();
                trans.setCouponList(coupList);
                //now to test the addCoupon method, we'll remove one from the list and re-add it
                CouponBO tempCoup = trans.getCouponList().remove(coupList.size()-1);
                trans.addCoupon(tempCoup);
                trans.applyCoupons();       //apply all of the coupons that are applicable
                trans.calcSubTotal();
                trans.calcTax();
                trans.calcTotal();
                UpdateController.getInstance().post_sale(trans);
                System.out.println("Transaction created: ID = " + trans.getTransID() + ", Date = " + trans.getTransDate() + ", Discount = " + trans.getTotalDiscountTaken() +
                        ", SubTotal = " + trans.getTransSubTotal() + ", Tax = " + trans.getTransTax() + " (at " + trans.getTransTaxRate() +
                        " tax rate), Total = " + trans.getTransTotal() + ", Status = " + trans.getTransStatus());
                
                //now make the payment
                /* Testing Payment*/
                System.out.println("\n\t===================================================================");
                System.out.println("\tTesting Payment (to update Transaction):");
                
                //create and build payment
                PaymentBO pmt = PaymentDAO.getInstance().create();
                pmt.setType("Cash");
                pmt.setPmtAmount(200.00);
                pmt.setPmtChange(trans.calcChange(pmt.getPmtAmount())); //calculate the change and add it to the payment
                PaymentDAO.getInstance().save(pmt);                 //save the payment
                
                //test that payment comes out of the cache
                PaymentBO pmt2 = PaymentDAO.getInstance().read(pmt.getPaymentID());
                System.out.println("\tRequested from Payment: pmt==pmt2 -> " + (pmt == pmt2));
                System.out.println("\tPayment retrieved from cache: Id = " + pmt.getPaymentID() + ", " +
                        pmt.getType() + ", " + pmt.getPmtAmount() + ", " + pmt.getPmtChange());
                
                //test that payment can be updated (even though it probably rarely will be), and can be retrieved from the DB
                pmt.setPmtAmount(150.00);
                pmt.setPmtChange(trans.calcChange(pmt.getPmtAmount()));
                PaymentDAO.getInstance().save(pmt);
                Cache.getInstance().clear();
                PaymentBO pmt3 = PaymentDAO.getInstance().read(pmt.getPaymentID());
                System.out.println("\tPayment updated and retrieved from DB: ID = " + pmt3.getPaymentID() + ", " +
                        pmt3.getType() + ", " + pmt3.getPmtAmount() + ", " + pmt3.getPmtChange());
                
                //now test that Transaction can be updated with the new payment
                trans.setPmt(pmt3);
                UpdateController.getInstance().post_sale(trans);
               
                //check to make sure the transaction can be retrieved from cache
                TransactionBO trans2 = TransactionDAO.getInstance().read(trans.getTransID());
                System.out.println("\nRequested Transaction from Cache through Read: trans==trans2 -> " + (trans == trans2));
                System.out.println("Transaction retrieved from cache: Id = " + trans2.getTransID() + ", Date = " +
                        trans2.getTransDate() + ", Total = " +  trans2.getTransTotal() + ", Status = " + trans2.getTransStatus());
                
                //check that the transaction can be retrieved from the DB
                Cache.getInstance().clear();
                TransactionBO trans3 = TransactionDAO.getInstance().read(trans.getTransID());
                System.out.println("Transaction retrieved from DB: Id = " + trans3.getTransID() + ", Date = " +
                        trans3.getTransDate() + ", Total = " +  trans3.getTransTotal() + ", Status = " + trans3.getTransStatus());
                
                
                /* Testing Return functionality*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Return Transaction:");
                String returnedItemID = "00000111a5c312c80000007f000002";
                //create and build the Transaction
                TransactionBO trans4 = TransactionDAO.getInstance().create();
                trans4.setSession(s);                                //setSession sets the StoreID and EmployeeID variables
                trans4.setCustomerID(cust.getCustID());
                trans4.setTransDate("2007-03-14");
                trans4.setTransStatus("Pending");        //set as 'Pending' just to test the change of that field
                trans4.setTransTaxRate(0.0);
                trans4.setOriginalTransID("0000011106c0a8ea0000017f000002");
                //retrieve the transaction_line from the original transaction for the item to be returned
                ArrayList<TransLineBO> retTxLines = TransLineDAO.getInstance().retrieveTransLine(trans4.getOriginalTransID(), returnedItemID);
                
                //at this point, if there were multiple instances of the revSrc purchased originally, a person would select one
                //but for our purposes, we'll simply choose the first item in the list.
                TransLineBO returnTxLine = TransLineDAO.getInstance().create();
                returnTxLine.setRevSrc(RSDAO_Factory.getInstance().getDAO("sale").read(returnedItemID));    //set returned item id for TxLine
                //set the line amount (refund amount, coupons are not refunded)
                returnTxLine.setLineAmount(retTxLines.get(0).getLineAmount());
                returnTxLine.setTransactionID(trans4.getTransID());
                trans4.addTxLine(returnTxLine);
                trans4.calcSubTotal();
                trans4.calcTotal();
                
                //since the payment for the original transaction was cash, a cash refund is given
                PaymentBO retPmt = PaymentDAO.getInstance().create();
                retPmt.setPmtAmount(0.0);
                retPmt.setPmtChange(trans4.getTransTotal());
                retPmt.setType("Cash");
                
                //set the new payment as the return transaction refund
                trans4.setPmt(retPmt);                
                UpdateController.getInstance().post_sale(trans4);
                System.out.println("Return Transaction created: ID = " + trans4.getTransID() + ", Date = " + trans4.getTransDate() + ", Discount = " + 
                        trans4.getTotalDiscountTaken() + ", For Item = " + returnTxLine.getRevSrc().getDescription() + ", Refund amount = " + 
                        trans4.getTransTotal() + ", for original transactionID = " + trans4.getOriginalTransID());

                /* Testing functionality changing pending transaction to void*/
                System.out.println("\n===========================================================================");
                System.out.println("Testing Transaction change to 'Void':");
                //create and build the Transaction
                TransactionBO trans5 = TransactionDAO.getInstance().create();
                trans5.setSession(s);                                //setSession sets the StoreID and EmployeeID variables
                trans5.setCustomerID(cust.getCustID());
                trans5.setTransDate("2007-03-11");
                trans5.setTransStatus("Pending");        //set as 'Pending' just to test the change of that field
                trans5.setTransTaxRate(0.0625);
                //add transactionLines for all Revenue Sources (for convenience) and apply all coupons as applicable
                for(int z=0; z<revSrcList.size(); z++){
                    //leave out "Laptop Repair" since it definitely requires 'Pending' status
                    if(!revSrcList.get(z).getDescription().equals("Laptop Repair")){
                        TransLineBO txLine = TransLineDAO.getInstance().create();
                        txLine.setTransactionID(trans5.getTransID());
                        txLine.setRevSrc(revSrcList.get(z));
                        trans5.addTxLine(txLine);
                    }
                }
                //get all of the coupons  (for convenience)
                trans5.setCouponList(coupList);
                //now to test the addCoupon method, we'll remove one from the list and re-add it
                trans5.applyCoupons();       //apply all of the coupons that are applicable
                trans5.calcSubTotal();
                trans5.calcTax();
                trans5.calcTotal();
                UpdateController.getInstance().post_sale(trans5);
                Cache.getInstance().clear();        //clear Cache to get a reading from the DB
                TransactionBO trans6 = TransactionDAO.getInstance().read(trans5.getTransID());
                System.out.println("Pending Transaction stored: ID = " + trans6.getTransID() + ", Date = " + trans6.getTransDate() + ", Discount = " + trans6.getTotalDiscountTaken() +
                        ", SubTotal = " + trans6.getTransSubTotal() + ", Tax = " + trans6.getTransTax() + " (at " + trans6.getTransTaxRate() +
                        " tax rate), Total = " + trans6.getTransTotal() + ", Status = " + trans6.getTransStatus());
                
                trans5.setTransStatus("Void");
                UpdateController.getInstance().post_sale(trans5);
                Cache.getInstance().clear();    //clear cache to get a reading from the DB
                trans6 = TransactionDAO.getInstance().read(trans5.getTransID());
                System.out.println("Pending Transaction set to 'Void': ID = " + trans6.getTransID() + ", Date = " + trans6.getTransDate() + ", Discount = " + trans6.getTotalDiscountTaken() +
                        ", SubTotal = " + trans6.getTransSubTotal() + ", Tax = " + trans6.getTransTax() + " (at " + trans6.getTransTaxRate() +
                        " tax rate), Total = " + trans6.getTransTotal() + ", Status = " + trans6.getTransStatus());
                
        
                /*Reading all objects for Milestone2*/
                System.out.println("\n===========================================================================");
                System.out.println("Reading all tables for MS2:");
                
                //Read Employees
                ArrayList<EmployeeBO> empList = EmployeeDAO.getInstance().readAllEmployees();
                System.out.println("\nEmployee List:");
                for(int i=0; i<empList.size(); i++){
                    EmployeeBO empItem = empList.get(i);
                    System.out.println("ID = " + empItem.getEmployeeID() + ", " + empItem.getEmpFullName());
                }
                
                //Read Stores
                ArrayList<StoreBO> storeList = StoreDAO.getInstance().readAllStores();
                System.out.println("\nStore List:");
                for(int i=0; i<storeList.size(); i++){
                    StoreBO storeItem = storeList.get(i);
                    System.out.println("ID = " + storeItem.getStoreID() + ", " + storeItem.getAddress() + ", " + storeItem.getCity());
                }
                
                //Read Positions
                ArrayList<PositionBO> posList = PositionDAO.getInstance().readAllPositions();
                System.out.println("\nPosition List:");
                for(int i=0; i<posList.size(); i++){
                    PositionBO posItem = posList.get(i);
                    System.out.println("ID = " + posItem.getPositionID() + ", " + posItem.getTitle() + ", " + posItem.getSalary());
                }
                
                //Read Transactions
                ArrayList<TransactionBO> transList = TransactionDAO.getInstance().readAllTrans();
                System.out.println("\nTransaction List:");
                for(int i=0; i<transList.size(); i++){
                    TransactionBO transItem = transList.get(i);
                    System.out.println("\nTransaction ID = " + transItem.getTransID() + ", Status = " + transItem.getTransStatus() + ", Subtotal = " + transItem.getTransSubTotal() +
                            ", Discounts = " + transItem.getTotalDiscountTaken() + ", Total = " + transItem.getTransTotal());
                    
                    //Read Transaction lines for this Transaction
                    ArrayList<TransLineBO> txLineList = transItem.getTxLineList();
                    System.out.println("\tTransaction Lines for this transaction:");
                    for(int x=0; x<txLineList.size(); x++){
                        TransLineBO txLineItem = txLineList.get(x);
                        System.out.println("-> ID = " + txLineItem.getTxLineID() + ", RevSrcID = " + txLineItem.getRevSrc().getRevSrcID() + ", Discount = " +
                                txLineItem.getDiscountTaken() + ", Line Amount = " + txLineItem.getLineAmount());
                    }
                }
                
                //Read All Transaction Lines in DB
                ArrayList<TransLineBO> txLineList = TransLineDAO.getInstance().readAllTxLine();
                System.out.println("\n\nList of ALL Transaction Lines:");
                for(int x=0; x<txLineList.size(); x++){
                    TransLineBO txLineItem = txLineList.get(x);
                    System.out.println("ID = " + txLineItem.getTxLineID() + ", RevSrcID = " + txLineItem.getRevSrc().getRevSrcID() + ", Discount = " +
                            txLineItem.getDiscountTaken() + ", Line Amount = " + txLineItem.getLineAmount());
                }
                
                //Read Coupons
                System.out.println("\nCoupon List:");
                for(int i=0; i<coupList.size(); i++){
                    CouponBO coupItem = coupList.get(i);
                    System.out.println("ID = " + coupItem.getCouponID() + ", " + coupItem.getDescription() + ", Amount = " + coupItem.getCoupAmount() +
                            ", Percentage = " + coupItem.getCoupPercent() + ", " + coupItem.getStartDate() + ", " + coupItem.getExpireDate() +
                            ", RevSrcID = " + coupItem.getRevSrcType());
                }
                
                //Read Revenue Sources
                System.out.println("\nRevenue Source List:");
                for(int i=0; i<revSrcList.size(); i++){
                    RevenueSourceBO revSrcItem = revSrcList.get(i);
                    System.out.println("ID = " + revSrcItem.getRevSrcID() + ", " + revSrcItem.getDescription() + ", $" + revSrcItem.getPrice() + 
                            ", " + revSrcItem.getType());
                }
                
                //Read Payment
                ArrayList<PaymentBO> pmtList = PaymentDAO.getInstance().readAllPmt();
                System.out.println("\nPayment List:");
                for(int i=0; i<pmtList.size(); i++){
                    PaymentBO pmtItem = pmtList.get(i);
                    System.out.println("ID = " + pmtItem.getPaymentID() + ", " + pmtItem.getPmtAmount() + ", " + pmtItem.getPmtChange() + ", " +
                            pmtItem.getType());
                }
                
                System.out.println("\n\nTester.java has ended successfully!");
                System.out.println("===========================================================================");
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
    }//main
}//class